﻿using System.Collections.Generic;
using System.Drawing;

namespace IML.Shared
{
    public class ImageCompilerRequest : NestedShape
    {
        public Brush InitialBrush { get; set; }
        public int CanvasWidth {get; set;}
        public int CanvasHeight {get; set;}
    }

    public abstract class ShapeContainer
    { 
        public List<KeyValuePair<string, NestedShape>> ShapeDeclarations { get; private set; }
        public List<Invocation> Invocations {get; private set;}

        public ShapeContainer()
        {
            ShapeDeclarations = new List<KeyValuePair<string, NestedShape>>();
            Invocations = new List<Invocation>();
        }
    }

    public abstract class NestedShape : ShapeContainer
    {
    }

    public abstract class Invocation
    { 
    }

    public class BrushInvocation : Invocation 
    {
        public Brush Brush { get; set; }
    }

    public class ShapeInvocation : Invocation
    {
        public NestedShape Shape { get; set; }
    }

    public class ShapeVariableInvocation : Invocation
    {
        public string VariableName;
        public int recusionDepth;
    }
    

    public class Brush
    {
        public Color FillColor { get; set; }
        public byte R { get; set; }
        public byte G { get; set; }
        public byte B { get; set; }
    }

    public class XYAttribute
    {
        public bool MaintainAspectRatio { get; set; }
        public float X { get; set; }
        public float Y { get; set; }
    }


    public class Ellipse : NestedShape
    {
        public XYAttribute Center {get; set;}
        public XYAttribute XYRadius {get;set;}

        public override string ToString()
        {
            return string.Format("Ellipse, Center({0}, {1})", Center.X, Center.Y);
        }
    }

    public class Polygon : NestedShape
    {
        public PointProducerFunction PointsFunction { get; set; }
        public override string ToString()
        {
            return "Polygon";
        }
    }


    public abstract class PointProducerFunction{ }

    public abstract class GeometicPointProducerFunction : PointProducerFunction
    {
        public List<float> AbsolutePositions { get; private set;}
        
        public GeometicPointProducerFunction(IEnumerable<float> absolutePositions) : this()
        {
            AbsolutePositions.AddRange(absolutePositions);
        }

        public GeometicPointProducerFunction(int numberOfPoints, float offset) :this()
        {
            float delta = 1f / numberOfPoints;
            for (int i = 0; i < numberOfPoints; i++)
            {
                AbsolutePositions.Add(delta * i + offset);
            }
        }

        internal GeometicPointProducerFunction()
        {
            AbsolutePositions = new List<float>();
        }
    }
    public class PointList : PointProducerFunction
    {
        public XYAttribute[] Verticies { get; set; }
    }

    public class EllipseFunction : GeometicPointProducerFunction
    {
        public XYAttribute[] Radiuses{get; set;}
        public XYAttribute Center { get; set; }
        public EllipseFunction(int numberOfPoints, float offset) : base(numberOfPoints, offset) { }
        public EllipseFunction(IEnumerable<float> absolutePositions) : base(absolutePositions) { }

    }

    public class LineFunction : GeometicPointProducerFunction
    {
        public XYAttribute Start { get; set; }
        public XYAttribute End { get; set; }
        public LineFunction(int numberOfPoints, float offset) : base(numberOfPoints, offset) { }
        public LineFunction(IEnumerable<float> absolutePositions) : base(absolutePositions) { }
    }

    public class Repeater : ShapeVariableInvocation
    { 
        public PointProducerFunction PointFunction {get; set;}
    }

    internal class DrawingContext
    {
    
    }
}